/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package com.dejax.service.impl;

import com.dejax.domain.BaseSysFunction;
import com.dejax.domain.BaseSysTransaction;
import com.dejax.exception.BadRequestException;
import com.dejax.service.dto.BaseSysFunctionQueryCriteria;
import com.dejax.utils.ValidationUtil;
import com.dejax.utils.FileUtil;
import lombok.RequiredArgsConstructor;
import com.dejax.repository.BaseSysTransactionRepository;
import com.dejax.service.BaseSysTransactionService;
import com.dejax.service.dto.BaseSysTransactionDto;
import com.dejax.service.dto.BaseSysTransactionQueryCriteria;
import com.dejax.service.mapstruct.BaseSysTransactionMapper;
import org.hibernate.query.NativeQuery;
import org.hibernate.transform.Transformers;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.dejax.utils.PageUtil;
import com.dejax.utils.QueryHelp;

import java.math.BigDecimal;
import java.util.*;
import java.io.IOException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.http.HttpServletResponse;

import static org.springframework.http.HttpStatus.BAD_REQUEST;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author Richer
* @date 2021-12-29
**/
@Service
@RequiredArgsConstructor
public class BaseSysTransactionServiceImpl implements BaseSysTransactionService {

    private final BaseSysTransactionRepository baseSysTransactionRepository;
    private final BaseSysTransactionMapper baseSysTransactionMapper;
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Map<String,Object> queryAll(BaseSysTransactionQueryCriteria criteria, Pageable pageable){
        criteria.setFlag(0);
        Page<BaseSysTransaction> page = baseSysTransactionRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(baseSysTransactionMapper::toDto));
    }

    @Override
    public List<BaseSysTransactionDto> queryAll(BaseSysTransactionQueryCriteria criteria){
        criteria.setFlag(0);
        return baseSysTransactionMapper.toDto(baseSysTransactionRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }


    @Override
    public Page<BaseSysTransaction>  queryAllData(BaseSysTransactionQueryCriteria criteria, Pageable pageable){
        StringBuffer dataBuffer = new StringBuffer(
                "SELECT transinfo.*,appinfo.appname,funcinfo.funcname " +
                        "FROM base_sys_transaction transinfo " +
                        "left join base_sys_appinfo appinfo on  appinfo.appid =transinfo.appid " +
                        "left join base_sys_function funcinfo on  funcinfo.funcid =transinfo.funcid " +
                        "WHERE 1 = 1 ");
        StringBuffer countBuffer = new StringBuffer(
                "SELECT count(*) " +
                        "FROM base_sys_transaction transinfo " +
                        "left join base_sys_appinfo appinfo on  appinfo.appid =transinfo.appid " +
                        "left join base_sys_function funcinfo on  funcinfo.funcid =transinfo.funcid " +
                        "WHERE 1 = 1 ");

        StringBuffer paramBuffer = new StringBuffer();

        //功能名称
        if(criteria.getTranscode() != null){
            paramBuffer.append(" AND transinfo.transcode like '%" + criteria.getTranscode() + "%'");
        }

        paramBuffer.append(" AND transinfo.flag = 0");
        StringBuffer orderBuffer = new StringBuffer(
                "");

        String dataSql = (dataBuffer.append(paramBuffer).append(orderBuffer))
                .toString();
        String countSql = (countBuffer.append(paramBuffer)).toString();

        System.out.println("{} dataSql= " + dataSql);
        System.out.println("{} countSql= " + countSql);

        Query dataQuery = entityManager.createNativeQuery(dataSql.toString());
        Query countQuery = entityManager.createNativeQuery(countSql.toString());

        dataQuery.setFirstResult((int) pageable.getOffset());
        dataQuery.setMaxResults(pageable.getPageSize());
        dataQuery.unwrap(NativeQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        BigDecimal count = BigDecimal.valueOf(Integer.valueOf(String.valueOf(countQuery.getSingleResult())));
        Integer total = count.intValue();

        List content = total > pageable.getOffset() ? dataQuery
                .getResultList() : Collections.emptyList();
        return new PageImpl<BaseSysTransaction>(content,pageable,total);
    }

    @Override
    @Transactional
    public BaseSysTransactionDto findById(String transid) {
        BaseSysTransaction baseSysTransaction = baseSysTransactionRepository.findById(transid).orElseGet(BaseSysTransaction::new);
        ValidationUtil.isNull(baseSysTransaction.getTransid(),"BaseSysTransaction","transid",transid);
        return baseSysTransactionMapper.toDto(baseSysTransaction);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseSysTransactionDto create(BaseSysTransaction resources) {
        resources.setTransid(IdUtil.simpleUUID());
        resources.setFlag(0);
        if(baseSysTransactionRepository.findOneByTranscode(resources.getAppid(),resources.getFuncid(),resources.getTranscode()) != null){
            throw new BadRequestException(BAD_REQUEST, "该交易编码已存在");

        }
        return baseSysTransactionMapper.toDto(baseSysTransactionRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(BaseSysTransaction resources) {
        BaseSysTransaction baseSysTransaction = baseSysTransactionRepository.findById(resources.getTransid()).orElseGet(BaseSysTransaction::new);
        ValidationUtil.isNull( baseSysTransaction.getTransid(),"BaseSysTransaction","id",resources.getTransid());
        baseSysTransaction.copy(resources);
        baseSysTransactionRepository.save(baseSysTransaction);
    }

    @Override
    public void deleteAll(String[] ids) {
        BaseSysTransaction updatesource = new BaseSysTransaction();
        for (String transid : ids) {
            updatesource.setTransid(transid);
            updatesource.setFlag(1);
            this.update(updatesource);
        }
    }

    @Override
    public void download(List<BaseSysTransactionDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (BaseSysTransactionDto baseSysTransaction : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("交易编码", baseSysTransaction.getTranscode());
            map.put("交易说明", baseSysTransaction.getTransdesc());
            map.put("交易类型", baseSysTransaction.getTranstype());
            map.put("程序代码", baseSysTransaction.getProgramcode());
            map.put("功能", baseSysTransaction.getFuncid());
            map.put("应用", baseSysTransaction.getAppid());
            map.put(" flag",  baseSysTransaction.getFlag());
            map.put(" notes",  baseSysTransaction.getNotes());
            map.put(" reguser",  baseSysTransaction.getReguser());
            map.put(" regtime",  baseSysTransaction.getRegtime());
            map.put(" moduser",  baseSysTransaction.getModuser());
            map.put(" modtime",  baseSysTransaction.getModtime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}